/**
 * 网络请求工具类
 * 基于 uni.request 封装
 */

import store from '@/store'

// 基础URL配置
// 真机调试：使用局域网IP（确保手机和电脑在同一WiFi）
// 微信开发者工具：使用localhost
const BASE_URL = process.env.NODE_ENV === 'development'
 ? 'http://localhost:8080/api'
  //? 'http://192.168.1.7:8080/api' // 开发环境接口地址（真机调试用局域网IP）
  : 'https://xindian66.xyz/api' // 生产环境接口地址

// Sa-Token配置
const TOKEN_NAME = 'ss_satoken'; // 与后端配置保持一致

/**
 * 请求拦截器
 * @param {Object} config 请求配置
 * @returns {Object} 处理后的请求配置
 */
const requestInterceptor = (config) => {
  // 检查是否是登录、注册或微信登录请求（这些请求不需要token）
  const isAuthRequest = config.url.includes('/user/login') || config.url.includes('/user/register') || config.url.includes('/user/wx/login');
  
  // 获取token并添加到请求头（非登录/注册请求）
  const token = uni.getStorageSync(TOKEN_NAME);
  
  if (token && !isAuthRequest) {
    config.header = {
      ...config.header,
      // Sa-Token标准请求头格式，使用与后端一致的token名称
      [TOKEN_NAME]: token,
      'Authorization': 'Bearer ' + token
    }
    
    // 同时在请求参数中添加token (适用于GET请求)
    if (config.method === 'GET' && config.params) {
      config.params[TOKEN_NAME] = token
    }
    
    // 为POST等请求添加token参数
    // 注意：如果data是数组，则不要添加token字段，因为后端期望数组格式
    if (config.method !== 'GET' && config.data && typeof config.data === 'object' && !Array.isArray(config.data)) {
      // 避免直接修改原始数据对象
      if (!config.data[TOKEN_NAME]) {
        config.data = {
          ...config.data,
          [TOKEN_NAME]: token
        }
      }
    }
  }
  
  // 确保登录和注册接口的URL正确
  if (isAuthRequest) {
    // 确保路径前面有/api前缀
    if (!config.url.includes('/api/')) {
      config.url = config.url.replace('/user/', '/api/user/');
    }
    
    // 确保请求头包含正确的Content-Type
    config.header = {
      ...config.header,
      'Content-Type': 'application/json'
    };
    
    ////console.log('认证请求:', config.url, config.data);
  }
  
  // 显示加载提示
  if (config.showLoading !== false) {
    uni.showLoading({
      title: '加载中...',
      mask: true
    })
    
    // 设置全局加载状态
    store.commit('SET_LOADING', true)
  }
  
  // 处理URL，确保不会重复添加/api前缀
  if (config.url.startsWith('/api/') && BASE_URL.endsWith('/api')) {
    config.url = config.url.replace('/api/', '/');
  }
  
  ////console.log('请求拦截器处理后的配置:', JSON.stringify(config))
  return config
}

/**
 * 响应拦截器
 * @param {Object} response 响应结果
 * @param {Object} config 请求配置
 * @returns {Promise} 处理后的响应结果
 */
const responseInterceptor = (response, config) => {
  // 隐藏加载提示
  if (config.showLoading !== false) {
    uni.hideLoading()
    store.commit('SET_LOADING', false)
  }
  
  // 请求成功，但需要判断业务状态码
  if (response.statusCode === 200) {
    const { code, data, message, msg } = response.data
    
    // 业务处理成功
    if (code === 0 || code === 200) {
      return data
    } 
    // token过期或未登录
    else if (code === 401) {
      uni.showToast({
        title: '登录已过期，请重新登录',
        icon: 'none'
      })
      
      // 清除登录状态
      uni.removeStorageSync(TOKEN_NAME)
      store.commit('user/CLEAR_USER')
      
      // 跳转到登录页
      setTimeout(() => {
        uni.reLaunch({
          url: '/pages/user/login'
        })
      }, 1500)
      
      return Promise.reject({ message: '登录已过期' })
    } 
    // 其他业务错误
    else {
      const errorMsg = message || msg || '操作失败'
      uni.showToast({
        title: errorMsg,
        icon: 'none'
      })
      
      return Promise.reject({ message: errorMsg })
    }
  } 
  // HTTP错误
  else {
    const errorMsg = `网络错误(${response.statusCode})`
    uni.showToast({
      title: errorMsg,
      icon: 'none'
    })
    
    return Promise.reject({ message: errorMsg })
  }
}

/**
 * 统一请求方法
 * @param {Object} options 请求选项
 * @returns {Promise} 请求结果
 */
const request = (options) => {
  ////console.log('请求方法接收到选项:', JSON.stringify(options))
  
  // 处理URL
  const url = options.url.startsWith('http') ? options.url : BASE_URL + options.url
  
  // 处理请求数据
  const method = options.method.toUpperCase()
  let data = {}
  
  if (method === 'GET') {
    data = options.params || options.data || {}
  } else {
    data = options.data || {}
  }
  
  // 合并配置
  const config = {
    url,
    method,
    data,
    header: options.headers || {},
    showLoading: options.showLoading
  }
  
  // 请求拦截
  const requestConfig = requestInterceptor(config)
  
  ////console.log('发送请求:', requestConfig.method, requestConfig.url, JSON.stringify(requestConfig.data), JSON.stringify(requestConfig.header))
  
  // 发起请求
  return new Promise((resolve, reject) => {
    uni.request({
      ...requestConfig,
      success: (res) => {
        ////console.log('请求响应:', JSON.stringify(res))
        try {
          const result = responseInterceptor(res, requestConfig)
          resolve(result)
        } catch (error) {
          //console.error('响应处理错误:', error)
          reject(error)
        }
      },
      fail: (err) => {
        //console.error('请求失败:', JSON.stringify(err))
        // 隐藏加载提示
        if (config.showLoading !== false) {
          uni.hideLoading()
          store.commit('SET_LOADING', false)
        }
        
        // 显示错误提示
        uni.showToast({
          title: '网络异常，请稍后再试',
          icon: 'none'
        })
        
        reject({ message: '网络异常，请稍后再试' })
      }
    })
  })
}

// 扩展常用请求方法
request.get = (url, params, options = {}) => {
  ////console.log('GET请求:', url, params)
  return request({
    url,
    method: 'GET',
    params,
    ...options
  })
}

request.post = (url, data, options = {}) => {
  ////console.log('POST请求:', url, data)
  return request({
    url,
    method: 'POST',
    data,
    ...options
  })
}

request.put = (url, data, options = {}) => {
  ////console.log('PUT请求:', url, data)
  return request({
    url,
    method: 'PUT',
    data,
    ...options
  })
}

request.delete = (url, data, options = {}) => {
  ////console.log('DELETE请求:', url, data)
  return request({
    url,
    method: 'DELETE',
    data,
    ...options
  })
}

export default request
